package com.stars.easyms.base.http;

import com.stars.easyms.base.constant.HttpHeaderConstants;
import lombok.AllArgsConstructor;
import org.slf4j.MDC;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;

/**
 * <p>className: EasyMsRequestSynchronizationManager</p>
 * <p>description: EasyMs的traceId、用户同步管理器</p>
 *
 * @author guoguifang
 * @date 2020-08-20 20:38
 * @since 1.6.1
 */
public final class EasyMsRequestSynchronizationManager {

    private static final ThreadLocal<TraceBean> TRACE_BEAN_THREAD_LOCAL = new NamedThreadLocal<>("Current rest trace info");

    private static final ThreadLocal<EasyMsRequestEntity> REQUEST_ENTITY_THREAD_LOCAL = new NamedThreadLocal<>("Current request entity trace info");

    private static final ThreadLocal<UserBean> EASY_MS_REST_USER_INFO_THREAD_LOCAL = new NamedThreadLocal<>("Current rest user info");

    /**
     * 把traceId和requestId放入日志线程本地变量中
     */
    public static void setTraceInfo(String traceId, String requestId) {
        TRACE_BEAN_THREAD_LOCAL.set(new TraceBean(traceId, requestId));
        MDC.put(HttpHeaderConstants.TRACE_KEY, "[traceId: " + traceId + "] ");
        MDC.put(HttpHeaderConstants.HEADER_KEY_REQUEST_ID, "[requestId: " + requestId + "] ");
    }

    @Nullable
    public static String getTraceId() {
        TraceBean traceBean = TRACE_BEAN_THREAD_LOCAL.get();
        if (traceBean != null) {
            return traceBean.traceId;
        }
        return null;
    }

    @Nullable
    public static String getRequestId() {
        TraceBean traceBean = TRACE_BEAN_THREAD_LOCAL.get();
        if (traceBean != null) {
            return traceBean.requestId;
        }
        return null;
    }

    public static void setRequestEntity(EasyMsRequestEntity easyMsRequestEntity) {
        REQUEST_ENTITY_THREAD_LOCAL.set(easyMsRequestEntity);
    }

    @Nullable
    public static EasyMsRequestEntity getRequestEntity() {
        return REQUEST_ENTITY_THREAD_LOCAL.get();
    }

    public static void setUserInfo(String userInfo, String decodedUserInfo) {
        EASY_MS_REST_USER_INFO_THREAD_LOCAL.set(new UserBean(userInfo, decodedUserInfo));
    }

    @Nullable
    public static String getCurrentUserInfo() {
        UserBean userBean = EASY_MS_REST_USER_INFO_THREAD_LOCAL.get();
        if (userBean != null) {
            return userBean.userInfo;
        }
        return null;
    }

    @Nullable
    public static String getDecodedCurrentUserInfo() {
        UserBean userBean = EASY_MS_REST_USER_INFO_THREAD_LOCAL.get();
        if (userBean != null) {
            return userBean.decodedUserInfo;
        }
        return null;
    }

    public static void clearTraceInfo() {
        // 清除日志线程本地变量中的traceId和requestId
        MDC.remove(HttpHeaderConstants.HEADER_KEY_REQUEST_ID);
        MDC.remove(HttpHeaderConstants.TRACE_KEY);
        TRACE_BEAN_THREAD_LOCAL.remove();
    }

    public static void clear() {
        EASY_MS_REST_USER_INFO_THREAD_LOCAL.remove();
        REQUEST_ENTITY_THREAD_LOCAL.remove();
        clearTraceInfo();
    }

    @AllArgsConstructor
    private static class TraceBean {

        private String traceId;

        private String requestId;
    }

    @AllArgsConstructor
    private static class UserBean {

        private String userInfo;

        private String decodedUserInfo;
    }

    private EasyMsRequestSynchronizationManager() {}

}